/*
 * Copyright (c) 2010, okazoh_tk. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  - Neither the name of the copyright holder nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "alkes/tree/Element.h"

namespace alkes {


Element::Element()
: flag_((1 << FLAG_DIRTY)|(1 << FLAG_VISIBLE))
{
}

Element::~Element()
{
}

void Element::setDirty(bool is_dirty)
{
    flag_.setFlag(FLAG_DIRTY, is_dirty);
}

bool Element::isDirty() const
{
    return flag_[FLAG_DIRTY];
}

void Element::setVisible(bool is_visible)
{
    if (is_visible != isVisible())
    {
        flag_.setFlag(FLAG_VISIBLE, is_visible);

        setDirty(true);
    }
}

bool Element::isVisible() const
{
    return flag_[FLAG_VISIBLE];
}

bool Element::isConstant() const
{
    return flag_[FLAG_CONSTANT];
}

void Element::setHittable(bool is_hittable)
{
    flag_.setFlag(FLAG_HITTABLE, is_hittable);
}

bool Element::isHittable() const
{
    return flag_[FLAG_HITTABLE];
}

bool Element::isModifiable() const
{
    return !flag_[FLAG_UNMODIFIABLE];
}

bool Element::isComposite() const
{
    return flag_[FLAG_IS_COMPOSITE];
}

bool Element::isDrawable() const
{
    return flag_[FLAG_DRAWABLE];
}

bool Element::hasSize() const
{
    return flag_[FLAG_HAS_SIZE];
}

bool Element::isRendering() const
{
    return flag_[FLAG_RENDERING];
}

bool Element::isUpdating() const
{
    return flag_[FLAG_UPDATING];
}

void Element::denyModify()
{
    flag_.setFlag(FLAG_UNMODIFIABLE);
}

void Element::allowModify()
{
    flag_.clearFlag(FLAG_UNMODIFIABLE);
}

void Element::setSystemFlag(uint32_t idx)
{
    flag_.setFlag(idx);
}

void Element::clearSystemFlag(uint32_t idx)
{
    flag_.clearFlag(idx);
}

bool Element::systemFlag(uint32_t idx) const
{
    return flag_[idx];
}

void Element::setFlag(uint32_t idx, bool is_on)
{
    if (FLAG_MAXIMUM <= idx)
        return ;

    flag_.setFlag(idx + FLAG_MAXIMUM, is_on);
}

void Element::clearFlag(uint32_t idx)
{
    if (FLAG_MAXIMUM <= idx)
        return ;

    flag_.clearFlag(idx + FLAG_MAXIMUM);
}

bool Element::flag(uint32_t idx) const
{
    if (FLAG_MAXIMUM <= idx)
        return false;

    return flag_[idx + FLAG_MAXIMUM];
}

}

